package com.example.questionnaire.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.utils.HttpUtils;
import com.example.common.utils.PageUtils;
import com.example.common.utils.Query;
import com.example.questionnaire.constant.TeamConstants;
import com.example.questionnaire.constant.UserConstants;
import com.example.questionnaire.dao.PieDao;
import com.example.questionnaire.dao.UserDao;
import com.example.questionnaire.dao.UserQuestionnaireDao;
import com.example.questionnaire.dao.UserTeamDao;
import com.example.questionnaire.dto.UserAddDto;
import com.example.questionnaire.entity.*;
import com.example.questionnaire.service.*;
import com.example.questionnaire.service.ex.UsernameDuplicatedException;
import org.apache.http.HttpResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import static com.example.common.utils.Constant.SALTVALUE;


@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, UserEntity> implements UserService {

    @Autowired
    private UserDao userDao;
    @Autowired
    private UserTeamDao userTeamDao;
    @Autowired
    private UserQuestionnaireDao userQuestionnaireDao;
    @Autowired
    private PieService pieService;
    @Autowired
    private PieDao pieDao;

    @Override
    public int reg(UserEntity user) {

        //通过user参数来获取传递过来的username
        String username = user.getUsername();
        //通过user参数来获取传递过来的username
        String telephone = user.getTelephone();
        //调用findByUsername(username)判断用户是否被注册过
        UserEntity result1 = userDao.findByUsername(username);
        UserEntity result2 = userDao.findByTelephone(telephone);

        if (result1 != null) {
            return 0;
        } else if (result2 != null) {
            return 2;
        }
        user.setIsDeleted(0);
        user.setManagerId(1);
        int rows = userDao.insert(user);
        return rows;
    }

    @Override
    public int login(String username, String password) {
        // 根据用户名称来查询用户的数据是否存在

        UserEntity result = userDao.findByUsername(username);

        if (result == null) {
            return 2;
        }
        if (!password.equals(result.getPassword())) {
            return 3;
        }
        if (result.getAuthority() == 0) {
            return 10;
        }
        return 0;
    }

    @Override
    public String getVcode(String telephone) {
        String host = "https://dfsns.market.alicloudapi.com";
        String path = "/data/send_sms";
        String method = "POST";
        String appcode = "6d23fc1aa20f4385b8aa7a07147d19a5";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求，定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();

        Random ne = new Random();//实例化一个random的对象ne
        int x = ne.nextInt(9999 - 1000 + 1) + 1000;//为变量赋随机值1000-9999
        String code = String.valueOf(x);
        String c = "code:" + code;
        bodys.put("content", c);
        bodys.put("phone_number", telephone);
        bodys.put("template_id", "TPL_0000");


        try {

            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            System.out.println(code);
            //获取response的body
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }


        return code;
    }

    @Override
    public int findPassword(String telephone, String password) {
        UserEntity user = userDao.findByTelephone(telephone);
        if (user == null) {
            return 1;
        }
        int result = userDao.findPassword(telephone, password);
        return result;
    }

    @Override
    public void setAuthority(String username) {

        UserEntity result = userDao.findByUsername(username);
        if (result.getAuthority() == 1) {
            userDao.setAuthority(username, 0);
        } else {
            userDao.setAuthority(username, 1);
        }
    }

    @Override
    public UserEntity findByUsername(String username) {
        UserEntity result = userDao.findByUsername(username);
        return result;
    }

    @Override
    public UserEntity findByTelephone(String telephone) {
        UserEntity result = userDao.findByTelephone(telephone);
        return result;
    }


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        Integer pagenum = Integer.parseInt(params.get("page").toString());
        Integer limit = Integer.parseInt(params.get("limit").toString());
        Page page = new Page(pagenum, limit);
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (params.containsKey("username")) {
            queryWrapper.like(UserEntity::getUsername,
                    params.get("username").toString());
        }
        queryWrapper.eq(UserEntity::getIsDeleted, 0);
        this.page(page, queryWrapper);
        return new PageUtils(page);
    }


    @Override
    public PageUtils queryPage1(Map<String, Object> params) {
        Integer pagenum = Integer.parseInt(params.get("page").toString());
        Integer limit = Integer.parseInt(params.get("limit").toString());
        Page page = new Page(pagenum, limit);
        int managerId = 0;
        if (params.containsKey("id")) {
            managerId = Integer.parseInt(params.get("id").toString());
        }
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(managerId != 0, UserEntity::getManagerId, managerId);
        if (params.containsKey("username")) {
            queryWrapper.like(UserEntity::getUsername,
                    params.get("username").toString());
        }
        queryWrapper.eq(UserEntity::getSign, 1);
        queryWrapper.eq(UserEntity::getIsDeleted, 0);
        this.page(page, queryWrapper);
        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage2(Map<String, Object> params) {
        Integer pagenum = Integer.parseInt(params.get("page").toString());
        Integer limit = Integer.parseInt(params.get("limit").toString());
        Page page = new Page(pagenum, limit);
        int managerId = 0;
        if (params.containsKey("id")) {
            managerId = Integer.parseInt(params.get("id").toString());
        }
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(managerId != 0, UserEntity::getManagerId, managerId);
        if (params.containsKey("username")) {
            queryWrapper.like(UserEntity::getUsername,
                    params.get("username").toString());
        }
        queryWrapper.eq(UserEntity::getSign, 2);
        queryWrapper.eq(UserEntity::getIsDeleted, 0);
        this.page(page, queryWrapper);
        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage3(Map<String, Object> params) {
        Integer pagenum = Integer.parseInt(params.get("page").toString());
        Integer limit = Integer.parseInt(params.get("limit").toString());
        Page page = new Page(pagenum, limit);
        int managerId = 0;
        if (params.containsKey("id")) {
            managerId = Integer.parseInt(params.get("id").toString());
        }
        LambdaQueryWrapper<UserEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (managerId != 1) {
            queryWrapper.eq(managerId != 0, UserEntity::getManagerId, managerId);
        }
        if (params.containsKey("username")) {
            queryWrapper.like(UserEntity::getUsername,
                    params.get("username").toString());
        }
        queryWrapper.eq(UserEntity::getSign, 3);
        queryWrapper.eq(UserEntity::getIsDeleted, 0);
        this.page(page, queryWrapper);
        return new PageUtils(page);
    }

    @Override
    public int userEnroll(Map<String, Object> params) {
        if (params.get("username") != null) {
            int tenantResult = userDao.queryExistUser(params);
            if (tenantResult != 0) {
                //用户名已经存在
                throw new UsernameDuplicatedException("用户名已经存在");
            }
        }
        int result = userDao.addUserInfo(params);
        return result;
    }

    @Override
    public int addUserInfo(UserEntity userEntity) {
        UserEntity user = userDao.findByUsername(userEntity.getUsername());
        if (user != null) {
            //用户名已经存在
//                throw new UsernameDuplicatedException("用户名已经存在");
            return 2;
        }
        // 获取原始密码
        String oldpassword = userEntity.getPassword();
        // 调用md5算法获取加密密码
        String md5Password = getMD5Password(oldpassword);
        // 将加密后的密码重新补全设置到user中
        userEntity.setPassword(md5Password);
        userEntity.setIsDeleted(0);
        if (userEntity.getSign() == 2) {
            return userDao.insert(userEntity);
        } else {
            return userDao.insertUser(userEntity);
        }
    }

    @Override
    public int addUserTeamInfo(UserAddDto userAddDto) {
        return userDao.addUserTeamInfo(userAddDto);
    }

    @Override
    public PageUtils queryByUserName(Map<String, Object> params) {
        IPage<UserEntity> page = this.page(
                new Query<UserEntity>().getPage(params), new QueryWrapper<UserEntity>()
        );
        return new PageUtils(page);
    }

    @Override
    public void modifyUserInfo(UserEntity userEntity) {
        userDao.modifyUserInfo(userEntity);
    }

    @Autowired
    UserService userService;

    @Override
    public int expenseUtoT(int userId, BigDecimal money) {
        QueryWrapper<UserEntity> queryWrapper1 = new QueryWrapper<>();
        UpdateWrapper<UserEntity> updateWrapper = new UpdateWrapper<>();
        queryWrapper1.eq("id", userId);

        UserEntity son = this.getById(userId);
        this.getById(userId);
        Integer managerId = son.getManagerId();

        UserEntity father = this.getById(managerId);

        BigDecimal newExpense = father.getExpense();
        newExpense = newExpense.add(money);
        updateWrapper.set("expense", newExpense).eq("id", managerId);
        userService.update(updateWrapper);
        return 0;
    }

    @Autowired
    TeamService teamService;

    @Transactional
    @Override
    public int delUserInfoById(UserEntity user) {
        //        完善无数据关联的用户
//        再查询一下数据库，防止前端给的数据不全
        int userId = user.getId();
        UserEntity one = this.getById(userId);
        int exist = 0;
        if (one.getSign().equals(UserConstants.tenant.getStatenum())) {
            //     如果是租户,查user表和user_team表和team表
            exist += this.count(new QueryWrapper<UserEntity>().eq("manager_id", userId));
            exist += userTeamService.count(new QueryWrapper<UserTeamEntity>().eq("user_id", userId));
            exist += teamService.count(new QueryWrapper<TeamEntity>().eq("personnel_id", userId));
        } else if (one.getSign().equals(UserConstants.user.getStatenum())) {
            //如果是用户，查user_answerer表和user_team表和team表
            exist += userAnswererService.count(new QueryWrapper<UserAnswererEntity>().eq("user_id", userId));
            exist += teamService.count(new QueryWrapper<TeamEntity>().eq("personnel_id", userId));
            exist += userTeamService.count(new QueryWrapper<UserTeamEntity>().eq("user_id", userId));
        }
        if (exist != 0) {
            return 3;
        }
        int count = 0;
        if (user.getSign() == 2) {
            count = userDao.delTenantInfoById(user.getId());
        }
//        if(userEntity.getSign() == UserConstants.user.getStatenum()){
//            userQuestionnaireDao.delUserQuestionnaireInfoById(userEntity.getId());
//            userTeamDao.delUserTeamInfoById(userEntity.getId());
//        }else if(userEntity.getSign()==UserConstants.tenant.getStatenum()){
//            userTeamDao.delUserTeamInfoById(userEntity.getId());
//        }
//        if(userEntity.getSign() == 2){//租户注销，
//            userQuestionnaireDao.delUserQuestionnaireInfoById(userEntity.getId());
//        }
        return count;
    }
    /**
     * 定义一个md5算法的加密处理
     */
    private String getMD5Password(String password) {
        // md5加密算法调用(三次加密)
        for (int i = 0; i < 3; i++) {
            password = DigestUtils.md5DigestAsHex((SALTVALUE + password + SALTVALUE).getBytes()).toUpperCase();
        }
        return password;
    }

    @Autowired
    AnswererTeamService answererTeamService;
    @Autowired
    UserTeamService userTeamService;

    @Override
    public int addMToT(int memberId, TeamEntity team) {
        if (team.getSign() == TeamConstants.answerer.getStatenum()) {
            AnswererTeamEntity answererTeam = new AnswererTeamEntity();
            answererTeam.setAnswererId(memberId);
            answererTeam.setTeamId(team.getId());
            answererTeamService.save(answererTeam);
        } else {
            UserTeamEntity userTeam = new UserTeamEntity();
            userTeam.setUserId(memberId);
            userTeam.setTeamId(team.getId());
            userTeamService.save(userTeam);
        }
        return 0;
    }

    @Override
    public int removeMFromT(int memberId, TeamEntity team) {
        if (team.getSign() == TeamConstants.answerer.getStatenum()) {
            QueryWrapper<AnswererTeamEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("answerer_id", memberId).eq("team_id", team.getId());
            answererTeamService.remove(wrapper);
        } else {
            QueryWrapper<UserTeamEntity> wrapper = new QueryWrapper<>();
            wrapper.eq("user_id", memberId).eq("team_id", team.getId());
            userTeamService.remove(wrapper);
        }
        return 0;
    }

    @Override
    public PageUtils queryTeamPage(Map<String, Object> params) {
        Integer pagenum = Integer.parseInt(params.get("page").toString());
        Integer limit = Integer.parseInt(params.get("limit").toString());
        Page<TeamEntity> page = new Page<>(pagenum, limit);
        QueryWrapper<TeamEntity> wrapper = new QueryWrapper<TeamEntity>();
        if (params.get("id") != null) {
            wrapper.eq("user.manager_id", params.get("id"));
        }

        IPage<Map<String, Object>> mapIPage = userDao.queryTeamPage(page, wrapper);
        List<Map<String, Object>> records = mapIPage.getRecords();
        PageUtils pageUtils = new PageUtils(records, (int) mapIPage.getTotal(), (int) mapIPage.getSize(), (int) mapIPage.getCurrent());
        return pageUtils;
    }

    @Override
    public PageUtils queryTenantQuestionnairePage(Map<String, Object> params) {
        Integer pagenum = Integer.parseInt(params.get("page").toString());
        Integer limit = Integer.parseInt(params.get("limit").toString());
        Page<QuestionnaireEntity> page = new Page<>(pagenum, limit);
        QueryWrapper<QuestionnaireEntity> wrapper = new QueryWrapper<QuestionnaireEntity>();
        if (params.get("id") != null) {
            wrapper.eq("user.manager_id", params.get("id"));
        }

        IPage<Map<String, Object>> mapIPage = userDao.queryTenantQuestionnairePage(page, wrapper);
        List<Map<String, Object>> records = mapIPage.getRecords();
        PageUtils pageUtils = new PageUtils(records, (int) mapIPage.getTotal(), (int) mapIPage.getSize(), (int) mapIPage.getCurrent());
        return pageUtils;

    }

    @Autowired
    AnswererService answererService;
    @Autowired
    UserAnswererService userAnswererService;

    @Override
    public PageUtils queryMNoInT(Map<String, Object> params) {

        QueryWrapper<UserTeamEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("team_id", params.get("teamId"));
        QueryWrapper<UserEntity> wrapper2 = new QueryWrapper<>();
        List<UserTeamEntity> list = userTeamService.list(wrapper);
        wrapper2.eq("manager_id", params.get("id")).eq("is_deleted", 0);
        List<Integer> collect = list.stream().map(item -> {
            Integer userId = item.getUserId();
            wrapper2.and(item1 -> {
                item1.ne("id", userId);
            });
            return userId;
        }).collect(Collectors.toList());
        IPage<UserEntity> page = userService.page(
                new Query<UserEntity>().getPage(params),
                wrapper2
        );
        return new PageUtils(page);


    }

    @Override
    public UserEntity queryByUserId(int id) {
        return userDao.queryByUserId(id);
    }

    @Override
    public List<PieEntity> analysis(Integer questionnaireId) {
        return pieDao.analysis(questionnaireId);
    }
}